#include "pch.h"
#include "include/mempipe.h"
#include "include/mutex.h"

//-------------------------------------------------------------------------------------
CMemPipe::CMemPipe()
{
	m_pBuffer = NULL;
	m_pTail = NULL;
	m_pHead = NULL;
	m_nSize = 0;
}
CMemPipe::CMemPipe(size_t nSize)
{
	m_pBuffer = NULL;
	m_pTail = NULL;
	m_pHead = NULL;
	m_nSize = 0;
	Init(nSize);
}
CMemPipe::~CMemPipe()
{
	UnInit();
}

bool CMemPipe::Init(size_t nSize)
{
	m_pBuffer = (char*)malloc(m_nSize);
	m_pTail = m_pHead = m_pBuffer;
	m_nSize = nSize;
	return m_pBuffer!=NULL;
}
void CMemPipe::UnInit()
{
	if (m_pBuffer)
	{
		free(m_pBuffer);
		m_pBuffer = NULL;
	}
}

bool CMemPipe::Write(const char* pData, size_t nLen)
{
	//static Mutex mutex;
	//mutex.lockMutex();
	size_t free_length = m_pTail >= m_pHead?(m_nSize - (m_pTail - m_pHead)):(m_pHead - m_pTail);
	if (free_length< nLen)
	{
		//mutex.unlockMutex();
		return false;
	}
	size_t endPos = m_pTail + nLen - m_pBuffer;
	if (endPos > m_nSize)
	{
		size_t copy1 = m_nSize - (m_pTail - m_pBuffer);
		memcpy(m_pTail, pData, copy1);
		size_t copy2 = endPos - m_nSize;
		memcpy(m_pBuffer, pData + copy1, copy2);
		m_pTail = m_pBuffer + copy2;
	}
	else
	{
		memcpy(m_pTail, pData, nLen);
		m_pTail += nLen;
	}
	//mutex.unlockMutex();
	return true;
}
bool CMemPipe::Read(char* pBuf, size_t nLen)
{
	//static Mutex mutex;
	//mutex.lockMutex();
	size_t length = m_pTail >= m_pHead ? (m_pTail - m_pHead) : (m_nSize - (m_pHead - m_pTail));
	if (length < nLen)
	{
		//mutex.unlockMutex();
		return false;
	}
	size_t endPos = m_pHead + nLen - m_pBuffer;
	if (endPos > m_nSize)
	{
		size_t copy1 = m_nSize - (m_pHead - m_pBuffer);
		memcpy(pBuf, m_pHead, copy1);
		size_t copy2 = endPos - m_nSize;
		memcpy(pBuf + copy1, m_pBuffer, copy2);
		m_pHead = m_pBuffer + copy2;
	}
	else
	{
		memcpy(pBuf, m_pHead, nLen);
		m_pHead += nLen;
	}
	//mutex.unlockMutex();
	return true;
}

bool CMemPipe::Discard(size_t nLen)
{
	//static Mutex mutex;
	//mutex.lockMutex();
	size_t length = m_pTail >= m_pHead ? (m_pTail - m_pHead) : (m_nSize - (m_pHead - m_pTail));
	if (length < nLen)
	{
		//mutex.unlockMutex();
		return false;
	}
	m_pHead += nLen;
	if (m_pHead > nLen+ m_pBuffer)
	{
		m_pHead -= m_nSize;
	}
	//mutex.unlockMutex();
	return true;
}

